---@class Battlegrounds.Engine : Base.Engine
---@field public carditems table<string, CardItem> @ 所有卡牌原型
---@field public minions table<string, Minion> @ 所有随从原型
---@field public spells table<string, Spell> @ 所有法术原型
---@field public weapons table<string, Weapon> @ 所有武器原型
---@field public minion_pool table<integer, Minion[]> @ 按等级分类的随从池
---@field public spell_pool table<integer, Spell[]> @ 按等级分类的法术池
local Engine = Fk.Base.Engine:subclass("Battlegrounds.Engine")

local RoomBase = require "packages.hearthstone.battlegrounds.core.roombase"
local CardItem = require "packages.hearthstone.battlegrounds.core.card.carditem"
local Minion = require "packages.hearthstone.battlegrounds.core.card.minion"
local Spell = require "packages.hearthstone.battlegrounds.core.card.spell"
local Weapon = require "packages.hearthstone.battlegrounds.core.card.weapon"

function Engine:initialize()
  Fk.Base.Engine.initialize(self)
  
  -- 初始化炉石卡牌系统
  self.carditems = {}      -- 所有卡牌原型
  self.minions = {}        -- 所有随从原型
  self.spells = {}         -- 所有法术原型
  self.weapons = {}        -- 所有武器原型
  
  -- 初始化卡牌池（按等级分类）
  self.minion_pool = {}    -- 随从池：level -> Minion[]
  self.spell_pool = {}     -- 法术池：level -> Spell[]
  
  -- 初始化等级池
  for i = 1, 6 do
    self.minion_pool[i] = {}
    self.spell_pool[i] = {}
  end
end

--- 添加卡牌到引擎
---@param carditem CardItem @ 要添加的卡牌
function Engine:addCardItem(carditem)
  assert(carditem:isInstanceOf(CardItem))
  
  if self.carditems[carditem.name] ~= nil then
    error(string.format("Duplicate carditem %s detected", carditem.name))
  end
  
  self.carditems[carditem.name] = carditem
  
  -- 根据类型分类存储
  if carditem:isType(CardItem.TypeMinion) then
    self.minions[carditem.name] = carditem
    if carditem.tavern_level and carditem.tavern_level >= 1 and carditem.tavern_level <= 6 then
      table.insert(self.minion_pool[carditem.tavern_level], carditem)
    end
  elseif carditem:isType(CardItem.TypeSpell) then
    self.spells[carditem.name] = carditem
    if carditem.tavern_level and carditem.tavern_level >= 1 and carditem.tavern_level <= 6 then
      table.insert(self.spell_pool[carditem.tavern_level], carditem)
    end
  elseif carditem:isType(CardItem.TypeWeapon) then
    self.weapons[carditem.name] = carditem
  end
end

--- 添加一系列卡牌
---@param carditems CardItem[] @ 要添加的卡牌列表
function Engine:addCardItems(carditems)
  for _, carditem in ipairs(carditems) do
    self:addCardItem(carditem)
  end
end

--- 获取指定等级的随从
---@param level integer @ 酒馆等级(1-6)
---@return Minion[] @ 该等级的随从列表
function Engine:getMinionsByLevel(level)
  return self.minion_pool[level] or {}
end

--- 获取指定等级的法术
---@param level integer @ 酒馆等级(1-6)
---@return Spell[] @ 该等级的法术列表
function Engine:getSpellsByLevel(level)
  return self.spell_pool[level] or {}
end

--- 从指定等级随机抽取随从
---@param level integer @ 酒馆等级
---@param count integer @ 抽取数量
---@return Minion[] @ 随机抽取的随从
function Engine:getRandomMinions(level, count)
  local pool = self:getMinionsByLevel(level)
  if #pool == 0 then
    return {}
  end
  
  local result = {}
  local available = table.simpleClone(pool)
  
  for i = 1, math.min(count, #available) do
    local index = math.random(#available)
    table.insert(result, available[index])
    table.remove(available, index)
  end
  
  return result
end

--- 从指定等级随机抽取法术
---@param level integer @ 酒馆等级
---@param count integer @ 抽取数量
---@return Spell[] @ 随机抽取的法术
function Engine:getRandomSpells(level, count)
  local pool = self:getSpellsByLevel(level)
  if #pool == 0 then
    return {}
  end
  
  local result = {}
  local available = table.simpleClone(pool)
  
  for i = 1, math.min(count, #available) do
    local index = math.random(#available)
    table.insert(result, available[index])
    table.remove(available, index)
  end
  
  return result
end

--- 根据名称获取卡牌
---@param name string @ 卡牌名称
---@return CardItem? @ 卡牌原型
function Engine:getCardItem(name)
  return self.carditems[name]
end

--- 根据名称获取随从
---@param name string @ 随从名称
---@return Minion? @ 随从原型
function Engine:getMinion(name)
  return self.minions[name]
end

--- 根据名称获取法术
---@param name string @ 法术名称
---@return Spell? @ 法术原型
function Engine:getSpell(name)
  return self.spells[name]
end

--- 根据名称获取武器
---@param name string @ 武器名称
---@return Weapon? @ 武器原型
function Engine:getWeapon(name)
  return self.weapons[name]
end

--- 克隆卡牌
---@param name string @ 卡牌名称
---@param new_name string? @ 新名称
---@return CardItem? @ 克隆的卡牌
function Engine:cloneCardItem(name, new_name)
  local carditem = self:getCardItem(name)
  if not carditem then
    return nil
  end
  
  return carditem:clone(new_name)
end

return Engine